home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 26 / AMIGAplus Sonderheft 26 (2000)(Falke)(DE)(Track 1 of 2)[!].iso / Tools / GFX-Viewer / Animviewer / mpegvideo_datatype / mpegparseblock.c < prev    next >
C/C++ Source or Header  |  1999-03-29  |  10KB  |  460 lines

  1.  
  2. /*
  3. **
  4. **  $VER: mpegparseblock.c 1.8 (27.5.97)
  5. **  mpegvideo.datatype 1.8
  6. **
  7. **  block parsing
  8. **
  9. **  Written 1996/1997 by Roland 'Gizzy' Mainz
  10. **
  11. */
  12.  
  13. /*
  14. #define NO_SANITY_CHECKS 1
  15. */
  16.  
  17. /* ansi includes */
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. /* project includes */
  22. #include "mpegmyassert.h"
  23. #include "mpegvideo.h"
  24. #include "mpegproto.h"
  25. #include "mpegdecoders.h"
  26.  
  27. /* External declarations. */
  28. extern const UBYTE zigzag_direct[ 64 ];
  29.  
  30. /*
  31.  *--------------------------------------------------------------
  32.  *
  33.  * ParseReconBlock --
  34.  *
  35.  *    Parse values for block structure from bitstream.
  36.  *      n is an indication of the position of the block within
  37.  *      the macroblock (i.e. 0-5) and indicates the type of
  38.  *      block (i.e. luminance or chrominance). Reconstructs
  39.  *      coefficients from values parsed and puts in
  40.  *      block.dct_recon array in vid stream structure.
  41.  *      sparseFlag is set when the block contains only one
  42.  *      coeffictient and is used by the IDCT.
  43.  *
  44.  * Results:
  45.  *
  46.  *
  47.  * Side effects:
  48.  *      Bit stream irreversibly parsed.
  49.  *
  50.  *--------------------------------------------------------------
  51.  */
  52.  
  53.  
  54. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  55. #define DECODE_DCT_COEFF_NEXT  DecodeDCTCoeffNext
  56.  
  57.  
  58. void ParseReconBlock( struct MPEGVideoInstData *mvid, int n )
  59. {
  60.   Block *blockPtr = (&(curVidStream -> block));
  61.   int    coeffCount = 0;
  62.  
  63.   if( bufLength < (100 * SSP) )
  64.   {
  65.     correct_underflow( mvid );
  66.   }
  67.  
  68.   {
  69.     int         diff;
  70.     int         size,
  71.                 level,
  72.                 i,
  73.                 run,
  74.                 pos,
  75.                 coeff;
  76.     short int  *reconptr;
  77.     UBYTE      *iqmatrixptr,
  78.                *niqmatrixptr;
  79.     int         qscale;
  80.  
  81.     reconptr = (blockPtr -> dct_recon)[ 0 ];
  82.  
  83.     /* Clear dct coeff matrix. */
  84.     memset( (void *)(blockPtr -> dct_recon), 0, sizeof( (blockPtr -> dct_recon) ) );
  85.  
  86.     if( curVidStream -> mblock . mb_intra )
  87.     {
  88.       if( n < 4 )
  89.       {
  90.         /*
  91.          * Get the luminance bits.  This code has been hand optimized to
  92.          * get by the normal bit parsing routines.  We get some speedup
  93.          * by grabbing the next 16 bits and parsing things locally.
  94.          * Thus, calls are translated as:
  95.          *
  96.          *    show_bitsX  <-->   next16bits >> (16-X)
  97.          *    get_bitsX   <-->   val = next16bits >> (16-flushed-X);
  98.          *               flushed += X;
  99.          *               next16bits &= bitMask[flushed];
  100.          *    flush_bitsX <-->   flushed += X;
  101.          *               next16bits &= bitMask[flushed];
  102.          *
  103.          * I've streamlined the code a lot, so that we don't have to mask
  104.          * out the low order bits and a few of the extra adds are removed.
  105.          *    bsmith
  106.          */
  107.         unsigned int next16bits,
  108.                      index,
  109.                      flushed;
  110.  
  111.         show_bits16( next16bits );
  112.         index = next16bits >> (16 - 7);
  113.         size    = dct_dc_size_luminance[ index ] . value;
  114.         flushed = dct_dc_size_luminance[ index ] . num_bits;
  115.         next16bits &= bitMask[ 16 + flushed ];
  116.  
  117.         if( size != 0 )
  118.         {
  119.           flushed += size;
  120.           diff = next16bits >> (16 - flushed);
  121.  
  122.           if( !(diff & bitTest[ 32 - size ]) )
  123.           {
  124.             diff = rBitMask[ size ] | (diff + 1);
  125.           }
  126.         }
  127.         else
  128.         {
  129.           diff = 0;
  130.         }
  131.  
  132.         flush_bits( flushed );
  133.  
  134.         if( n == 0 )
  135.         {
  136.           coeff = diff << 3;
  137.  
  138.           if( ((curVidStream -> mblock . mb_address) - (curVidStream -> mblock . past_intra_addr)) > 1 )
  139.           {
  140.             coeff += 1024;
  141.           }
  142.           else
  143.           {
  144.             coeff += (blockPtr -> dct_dc_y_past);
  145.           }
  146.  
  147.           (blockPtr -> dct_dc_y_past) = coeff;
  148.         }
  149.         else
  150.         {
  151.           coeff = (blockPtr -> dct_dc_y_past) + (diff << 3);
  152.           (blockPtr -> dct_dc_y_past) = coeff;
  153.         }
  154.       }
  155.       else
  156.       {
  157.         /*
  158.          * Get the chrominance bits.  This code has been hand optimized to
  159.          * as described above
  160.          */
  161.         unsigned int next16bits,
  162.                      index,
  163.                      flushed;
  164.  
  165.         show_bits16( next16bits );
  166.         index = next16bits >> (16 - 8);
  167.         size    = dct_dc_size_chrominance[ index ] . value;
  168.         flushed = dct_dc_size_chrominance[ index ] . num_bits;
  169.         next16bits &= bitMask[ 16 + flushed ];
  170.  
  171.         if( size != 0 )
  172.         {
  173.           flushed += size;
  174.           diff = next16bits >> (16 - flushed);
  175.  
  176.           if (!(diff & bitTest[ 32 - size ]))
  177.           {
  178.             diff = rBitMask[ size ] | (diff + 1);
  179.           }
  180.         }
  181.         else
  182.         {
  183.           diff = 0;
  184.         }
  185.  
  186.         flush_bits( flushed );
  187.  
  188.         if( n == 4 )
  189.         {
  190.           coeff = diff << 3;
  191.  
  192.           if( curVidStream -> mblock . mb_address - curVidStream -> mblock . past_intra_addr > 1 )
  193.           {
  194.             coeff += 1024;
  195.           }
  196.           else
  197.           {
  198.             coeff += (blockPtr -> dct_dc_cr_past);
  199.           }
  200.  
  201.           (blockPtr -> dct_dc_cr_past) = coeff;
  202.         }
  203.         else
  204.         {
  205.           coeff = diff << 3;
  206.  
  207.           if( curVidStream -> mblock . mb_address - curVidStream -> mblock . past_intra_addr > 1 )
  208.           {
  209.             coeff += 1024;
  210.           }
  211.           else
  212.           {
  213.             coeff += (blockPtr -> dct_dc_cb_past);
  214.           }
  215.  
  216.           (blockPtr -> dct_dc_cb_past) = coeff;
  217.         }
  218.       }
  219.  
  220.       *reconptr = coeff;
  221.       i   = 0;
  222.       pos = 0;
  223.       coeffCount = (coeff != 0);
  224.  
  225.       if( (curVidStream -> picture . code_type) != D_TYPE )
  226.       {
  227.         qscale      = curVidStream -> slice . quant_scale;
  228.         iqmatrixptr = curVidStream -> intra_quant_matrix[ 0 ];
  229.  
  230.         while( 1 )
  231.         {
  232.           DECODE_DCT_COEFF_NEXT( run, level );
  233.  
  234.           if( run == END_OF_BLOCK )
  235.             break;
  236.  
  237.           assert( run != ESCAPE );
  238.           assert( run != END_OF_BLOCK );
  239.  
  240.           i = i + run + 1;
  241.  
  242.           assert( (i < 64) && (i >= 0) );
  243.           i = ABS( i ) % 64;
  244.           pos = zigzag_direct[ i ];
  245.  
  246.           coeff = (level * qscale * ((int)iqmatrixptr[ pos ])) >> 3;
  247.  
  248.           if( level < 0 )
  249.           {
  250.             coeff += (coeff & 1);
  251.           }
  252.           else
  253.           {
  254.             coeff -= (coeff & 1);
  255.           }
  256.  
  257.           reconptr[ pos ] = coeff;
  258.  
  259.           if( coeff )
  260.           {
  261.             coeffCount++;
  262.           }
  263.         }
  264.  
  265.         flush_bits( 2 );
  266.  
  267.         goto end;
  268.       }
  269.     }
  270.     else
  271.     {
  272.       niqmatrixptr = curVidStream -> non_intra_quant_matrix[ 0 ];
  273.       qscale       = curVidStream -> slice . quant_scale;
  274.  
  275.       DECODE_DCT_COEFF_FIRST( run, level );
  276.  
  277. /*
  278.       assert( run != ESCAPE );
  279.       assert( run != END_OF_BLOCK );
  280. */
  281.  
  282.       i = run;
  283.  
  284.       assert( (i < 64) && (i >= 0) );
  285.       i = ABS( i ) % 64;
  286.       pos = zigzag_direct[ i ];
  287.  
  288.       if( level < 0 )
  289.       {
  290.         coeff = (((level << 1) - 1) * qscale * ((int)(niqmatrixptr[ pos ]))) >> 4;
  291.         coeff += (coeff & 1);
  292.       }
  293.       else
  294.       {
  295.         coeff = (((level << 1) + 1) * qscale * ((int)(*(niqmatrixptr + pos)))) >> 4;
  296.         coeff -= (coeff & 1);
  297.       }
  298.  
  299.       reconptr[ pos ] = coeff;
  300.  
  301.       if( coeff )
  302.       {
  303.         coeffCount = 1;
  304.       }
  305.  
  306.       if( curVidStream -> picture . code_type != D_TYPE )
  307.       {
  308.         while( 1 )
  309.         {
  310.           DECODE_DCT_COEFF_NEXT( run, level );
  311.  
  312.           if( run == END_OF_BLOCK )
  313.             break;
  314.  
  315. #ifdef COMMENTED_OUT
  316.           assert( run != ESCAPE );
  317. #endif /* COMMENTED_OUT */
  318.  
  319.           i = i + run + 1;
  320.  
  321.           assert( (i < 64) && (i >= 0) );
  322.           i = ABS( i ) % 64;
  323.           pos = zigzag_direct[ i ];
  324.  
  325.           if( level < 0 )
  326.           {
  327.             coeff = (((level << 1) - 1) * qscale * ((int)(niqmatrixptr[ pos ]))) >> 4;
  328.             coeff += (coeff & 1);
  329.           }
  330.           else
  331.           {
  332.             coeff = (((level << 1) + 1) * qscale * ((int)(*(niqmatrixptr + pos)))) >> 4;
  333.             coeff -= (coeff & 1);
  334.           }
  335.  
  336.           reconptr[ pos ] = coeff;
  337.  
  338.           if( coeff )
  339.           {
  340.             coeffCount++;
  341.           }
  342.         }
  343.  
  344.         flush_bits( 2 );
  345.  
  346.         goto end;
  347.       }
  348.     }
  349.  
  350. end:
  351.  
  352.     if( coeffCount == 1 )
  353.     {
  354.       j_rev_dct_sparse( mvid, reconptr, pos );
  355.     }
  356.     else
  357.     {
  358. #ifdef FLOATDCT
  359.       if( mvid -> mvid_Quality )
  360.       {
  361.         float_idct( reconptr );
  362.       } 
  363.       else
  364. #endif
  365.       {
  366.         j_rev_dct( reconptr );
  367.       }
  368.     }
  369.   }
  370. }
  371.  
  372.  
  373. /*
  374.  *--------------------------------------------------------------
  375.  *
  376.  * ParseAwayBlock --
  377.  *
  378.  *    Parses off block values, throwing them away.
  379.  *      Used with grayscale dithering.
  380.  *
  381.  * Results:
  382.  *    None.
  383.  *
  384.  * Side effects:
  385.  *      None.
  386.  *
  387.  *--------------------------------------------------------------
  388.  */
  389.  
  390.  
  391. void ParseAwayBlock( struct MPEGVideoInstData *mvid, int n )
  392. {
  393.   unsigned int diff;
  394.   unsigned int size,
  395.                run;
  396.   int          level;
  397.  
  398.   if( bufLength < (100 * SSP) )
  399.   {
  400.     correct_underflow(mvid);
  401.   }
  402.  
  403.   if( curVidStream -> mblock . mb_intra )
  404.   {
  405.     /* If the block is a luminance block... */
  406.     if( n < 4 )
  407.     {
  408.       /* Parse and decode size of first coefficient. */
  409.       DecodeDCTDCSizeLum( size );
  410.  
  411.       /* Parse first coefficient. */
  412.       if( size != 0 )
  413.       {
  414.         get_bitsn( size, diff );
  415.       }
  416.     }
  417.     else /* Otherwise, block is chrominance block... */
  418.     {
  419.       /* Parse and decode size of first coefficient. */
  420.       DecodeDCTDCSizeChrom( size );
  421.  
  422.       /* Parse first coefficient. */
  423.       if( size != 0 )
  424.       {
  425.         get_bitsn( size, diff );
  426.       }
  427.     }
  428.   }
  429.   else /* Otherwise, block is not intracoded... */
  430.   {
  431.     /* Decode and set first coefficient. */
  432.     DECODE_DCT_COEFF_FIRST( run, level );
  433.  
  434.     assert( run != ESCAPE );
  435.     assert( run != END_OF_BLOCK );
  436.   }
  437.  
  438.   /* If picture is not D type (i.e. I, P, or B)... */
  439.   if( curVidStream -> picture . code_type != D_TYPE )
  440.   {
  441.     /* While end of macroblock has not been reached... */
  442.     while( 1 )
  443.     {
  444.       /* Get the dct_coeff_next */
  445.       DECODE_DCT_COEFF_NEXT( run, level );
  446.  
  447.       if( run == END_OF_BLOCK )
  448.         break;
  449.  
  450.       assert( run != ESCAPE );
  451.       assert( run != END_OF_BLOCK );
  452.     }
  453.  
  454.     /* End_of_block */
  455.     flush_bits( 2 );
  456.   }
  457. }
  458.  
  459.  
  460.